package team.tunan.service.impl;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;
import team.tunan.entity.Game;
import team.tunan.entity.Matches;
import team.tunan.entity.Score;
import team.tunan.entity.User;
import team.tunan.entity.dto.MatchInfo;
import team.tunan.mapper.GameMapper;
import team.tunan.mapper.MatchesMapper;
import team.tunan.mapper.ScoreMapper;
import team.tunan.mapper.UserMapper;
import team.tunan.service.IMatchesService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author sqx
 * @since 2024-01-01
 */
@Service
public class MatchesServiceImpl extends ServiceImpl<MatchesMapper, Matches> implements IMatchesService {
    @Autowired
    private MatchesMapper matchMapper;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private ScoreMapper scoreMapper;

    @Autowired
    private GameMapper gameMapper;


    @Override
    public boolean isEnd(Matches matches) {
        User usera = userMapper.getUserById(matches.getPlayerA());
        User userb = userMapper.getUserById(matches.getPlayerB());

        List<User> enda = userMapper.isEnd(matches.getMatchId(),usera.getRoundNum());
        List<User> endb = userMapper.isEnd(matches.getMatchId(),userb.getRoundNum());
        if (enda.size()>0 || endb.size()>0){
            return false;
        }
        else {
            return true;
        }

    }

    @Override
    @Transactional
    public int doAdd(Matches matches) {
        Integer aid = matches.getPlayerA();
        Integer bid = matches.getPlayerB();

        String aSong = matches.getASong();
        String bSong = matches.getBSong();
        Integer matchId = matches.getMatchId();
        String matchname = matches.getMatchname();
        User userById = userMapper.getUserById(aid);
        Integer roundNum = userById.getRoundNum()+1;
        LocalDateTime now = LocalDateTime.now();
        // match 表新增一条对战记录
        int i = matchMapper.addMatch(aid, aSong, bid, bSong,matchId,matchname,roundNum,now);
        // 更改选手状态
        userMapper.updatePlayerStatusById(matchId,aid);
        userMapper.updatePlayerStatusById(matchId,bid);


        return i;
    }

    @Override
    public List<Map<String, Object>> getMatchInfo(Integer gid, Integer roundNum) {
        List<Map<String, Object>> match = matchMapper.getMatch(gid, roundNum);
//        List<Map<String, Object>> match = matchMapper.getMatchs(gid, roundNum);

        for (Map<String, Object> m : match) {
            System.out.println(m);
            Integer aid = (Integer) m.get("player_a");
            Integer bid = (Integer) m.get("player_b");
            User a = userMapper.getUserById(aid);
            User b = userMapper.getUserById(bid);
            Game game = gameMapper.getGame((Integer) m.get("match_id"));

            m.put("a_name", a.getUsername());
            m.put("b_name", b.getUsername());
            m.put("mname",game.getMname());
        }
        System.out.println(match);
        return match;
    }

    @Override
    public List<Map<String, Object>> getPlayerInfo(Integer gid) {
        Game game = gameMapper.getGame(gid);
        List<Map<String, Object>> playInfo = new ArrayList<>();
        if (game.getStatus() == 0){
            playInfo = userMapper.getPlayInfo();
        }else if(game.getStatus() == 1){
            playInfo = userMapper.getPlayInfoTwo(gid);
        }


        return playInfo;
    }

    @Override
    public boolean getMatchVerify() {
        List<Matches> matching = matchMapper.getMatching();
        if (matching.size()>0) {
            return true;
        }
        return false;
    }

    @Override
    public Matches getMatch(Integer mid) {
        Matches match = matchMapper.getMatchByMid(mid);
        Integer aid = match.getPlayerA();
        Integer bid = match.getPlayerB();
        String aName = userMapper.getUserById(aid).getUsername();
        String bName = userMapper.getUserById(bid).getUsername();
        match.setAName(aName);
        match.setBName(bName);

        return match;
    }

    @Override
    @Transactional
    public Map<String, Object> startMatches(Matches matches) {

        Map<String, Object> map = new HashMap<>();

        Integer mid = matches.getMid();

        User userById = userMapper.getUserById(matches.getPlayerA());
        Integer status = matchMapper.getMatchStatusById(mid);

        Game game = gameMapper.getGame(matches.getMatchId());//判断比赛场次所属大赛是否已经开启
        if(game.getStatus() == 0){
            map.put("status", 4);
            map.put("flag", true);
            return map;
        }


//        if(status ==0 && matches.getMStatus() ==2){
//            map.put("status", 1);//1的状态是活动还未开启不能直接结束
//            map.put("flag", false);
//            return map;
//        }


//        List<Integer> matchStatus = matchMapper.getMatchStatus();
//        if (matchStatus.contains(1)) {
//            map.put("status", 1);
//            map.put("flag", false);
//            return map;
//        }
        //将比赛状态改为1 表示 开启比赛
        matchMapper.updateMatchStatus(1, mid);

        //开启比赛之后 在数据库score表中中新建歌手信息

        // 获取选手id
        Integer aid = matches.getPlayerA();
        Integer bid = matches.getPlayerB();

        Score aScore = new Score();
        aScore.setMid(mid);
        aScore.setPlayerId(aid);
        aScore.setMatch_id(matches.getMatchId());
        aScore.setRoundNum(userById.getRoundNum());
        Score bScore = new Score();
        bScore.setMid(mid);
        bScore.setPlayerId(bid);
        bScore.setMatch_id(matches.getMatchId());
        bScore.setRoundNum(userById.getRoundNum());

        List<Score> scores = new ArrayList<>();
        scores.add(aScore);
        scores.add(bScore);
        scoreMapper.addPlayerScore(scores);
        map.put("status", 0);
        map.put("flag", true);
        return map;
    }





    /**
     * 结束比赛
     *
     * @param mid
     * @return
     */
    @Override
    public Map<String, Object> endMatches(Integer mid) {


        Map<String, Object> map = new HashMap<>();

        Integer status = matchMapper.getMatchStatusById(mid);
        System.out.println("status"+ status);
        if (status == 2) {
            map.put("status", 2);
            map.put("flag", false);
            return map;
        }

        if (status == 0) {
            map.put("status", 0);
            map.put("flag", false);
            return map;
        }


        // 计算歌手总成绩 获取该场比赛的 歌手id
        Matches match = matchMapper.getMatchByMid(mid);

        System.out.println("match" + match);
        Integer aid = match.getPlayerA();
        Integer bid = match.getPlayerB();

        Score aScore = scoreMapper.getVotesByPid(aid,match.getMatchId(),match.getRoundNum());
        Score bScore = scoreMapper.getVotesByPid(bid,match.getMatchId(),match.getRoundNum());


        Integer avote = aScore.getVotes();
        Integer bvote = bScore.getVotes();


        Integer allVote = avote + bvote;

        if (ObjectUtils.isEmpty(aScore.getJudgesScoring())){
            aScore.setJudgesScoring(BigDecimal.valueOf(0));
        }
        if (ObjectUtils.isEmpty(bScore.getJudgesScoring())){
            bScore.setJudgesScoring(BigDecimal.valueOf(0));
        }


        double aJScore = aScore.getJudgesScoring().doubleValue();
        double bJScore = bScore.getJudgesScoring().doubleValue();


        double as = 0;
        double bs = 0;
        double aTotalScore =0;
        double bTotalScore = 0;
        if(allVote != 0){
            as = (avote / (double) allVote) * 100;
            aTotalScore = Double.parseDouble(String.format("%.2f", as)) + aJScore;
            bs = (bvote / (double) allVote) * 100;
            bTotalScore = Double.parseDouble(String.format("%.2f", bs)) + bJScore;
        }
        if (aTotalScore >= bTotalScore) {
            scoreMapper.updateWin(aid);
        } else {
            scoreMapper.updateWin(bid);
        }

        System.out.println(aTotalScore + "    " + bTotalScore);
        scoreMapper.updateTotalScore(aTotalScore, aid);
        scoreMapper.updateTotalScore(bTotalScore, bid);


        //将比赛状态改为2 表示 结束比赛
        matchMapper.updateMatchStatus(2, mid);

        map.put("status", 1); // 标识
        map.put("flag", true);
        return map;
    }

    @Transactional
    public Map<String, Object> end(Matches matches) {
        Integer mid  = matches.getMid();

        Map<String, Object> map = new HashMap<>();

        Integer status = matchMapper.getMatchStatusById(mid);


        if(status ==0 && matches.getMStatus() ==2){
            map.put("status", 1);//1的状态是活动还未开启不能直接结束
            map.put("flag", false);
            return map;
        }
        // 计算歌手总成绩 获取该场比赛的 歌手id
        Matches match = matchMapper.getMatchByMid(mid);

        System.out.println("match" + match);
        Integer aid = match.getPlayerA();
        Integer bid = match.getPlayerB();

        Score aScore = scoreMapper.getVotesByPid(aid,match.getMatchId(),match.getRoundNum());
        Score bScore = scoreMapper.getVotesByPid(bid,match.getMatchId(),match.getRoundNum());


        Integer avote = aScore.getVotes();
        Integer bvote = bScore.getVotes();


        Integer allVote = avote + bvote;

        if (ObjectUtils.isEmpty(aScore.getJudgesScoring())){
            aScore.setJudgesScoring(BigDecimal.valueOf(0));
        }
        if (ObjectUtils.isEmpty(bScore.getJudgesScoring())){
            bScore.setJudgesScoring(BigDecimal.valueOf(0));
        }


        double aJScore = aScore.getJudgesScoring().doubleValue();
        double bJScore = bScore.getJudgesScoring().doubleValue();


        double as = 0;
        double bs = 0;
        double aTotalScore =0;
        double bTotalScore = 0;
        if(allVote != 0){
            as = (avote / (double) allVote) * 100;
            aTotalScore = Double.parseDouble(String.format("%.2f", as)) + aJScore;
            bs = (bvote / (double) allVote) * 100;
            bTotalScore = Double.parseDouble(String.format("%.2f", bs)) + bJScore;
        }
        if (aTotalScore >= bTotalScore) {
            scoreMapper.updateWin(aid);//将其设置为获胜
            userMapper.updatePromote(aid);
            userMapper.updatePlayerEndById(bid);
        } else {
            scoreMapper.updateWin(bid);
            userMapper.updatePromote(bid);
            userMapper.updatePlayerEndById(aid);
        }

        System.out.println(aTotalScore + "    " + bTotalScore);
        scoreMapper.updateTotalScore(aTotalScore, aid);
        scoreMapper.updateTotalScore(bTotalScore, bid);


        //将比赛场次状态改为2 表示 结束比赛
        matchMapper.updateMatchStatus(2, mid);






        map.put("status", 2); // 标识成功结束
        map.put("flag", true);
        return map;
    }
    /**
     * 修改比赛状态
     * @param matches
     * @return
     */
    @Override
    @Transactional
    public Map<String, Object> updateMatch(Matches matches) {
        Map<String, Object> map = new HashMap<>();

        Integer mid = matches.getMid();
        Integer status = matchMapper.getMatchStatusById(mid);
        if (status == 2) {
            map.put("status", 2);
            map.put("flag", false);
            return map;
        }
        //开启逻辑
        if(matches.getMStatus() == 1){
            map = startMatches(matches);
            return map;
        }else if(matches.getMStatus() == 2){//关闭逻辑
            map = end(matches);
            return map;
        }else {//暂停逻辑
            map = stop(matches);
            return map;
        }

    }

    @Override
    public Integer maxRoundNum(Integer gid) {
        Integer i = matchMapper.MaxRoundNum(gid);
        return i;
    }

    public Map<String, Object> stop(Matches matches){
        Integer mid  = matches.getMid();

        Map<String, Object> map = new HashMap<>();

        Integer status = matchMapper.getMatchStatusById(mid);

        if(status == 0){
            map.put("status", 1);//1的状态是活动还未开启不能直接暂停
            map.put("flag", false);
            return map;
        }
        int i = matchMapper.updateMatchStatus(3, mid);

        map.put("status", 3);
        map.put("flag", true);
        return map;
    }



    @Override
    public MatchInfo getMatchToShow(Integer mid) {
//        Matches matching = matchMapper.getMatching();


        Matches matching = matchMapper.getMatchByMid(mid);


        // id
        Integer aid = matching.getPlayerA();
        Integer bid = matching.getPlayerB();
        System.out.println("aid = " + aid);
        System.out.println("bid = " + bid);
        // name
        User ua = userMapper.getUserById(aid);
        User ub = userMapper.getUserById(bid);
//
        // 选手成绩信息
        Score a = scoreMapper.getVotesByPid(aid,matching.getMatchId(),matching.getRoundNum());
        Score b = scoreMapper.getVotesByPid(bid,matching.getMatchId(),matching.getRoundNum());
//
        System.out.println("a=" + a);
        System.out.println("b=" + b);
        MatchInfo matchInfo = new MatchInfo();

        matchInfo.setMid(matching.getMid());

        // id
        matchInfo.setPlayerA(aid);
        matchInfo.setPlayerB(bid);
//
        // name
        matchInfo.setAName(ua.getUsername());
        matchInfo.setBName(ub.getUsername());
//
        // 评委打分
        matchInfo.setAJudgesScoring(a.getJudgesScoring());
        matchInfo.setBJudgesScoring(b.getJudgesScoring());

        // 观众投票
        matchInfo.setAVotes(a.getVotes());
        matchInfo.setBVotes(b.getVotes());

        // 总成绩
        matchInfo.setATotalScore(a.getTotalScore());
        matchInfo.setBTotalScore(b.getTotalScore());

        // 头像地址
        matchInfo.setAPictureUrl(ua.getPictureUrl());
        matchInfo.setBPictureUrl(ub.getPictureUrl());

        return matchInfo;
    }

}
